package com.googlecode.roids.app;

import android.R;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnKeyListener;
import android.content.DialogInterface.OnClickListener;

public final class DialogUtil {
	
	public static final int ICON_ALERT 	= R.drawable.ic_dialog_alert;
	public static final int ICON_DIALER = R.drawable.ic_dialog_dialer;
	public static final int ICON_EMAIL 	= R.drawable.ic_dialog_email;
	public static final int ICON_INFO 	= R.drawable.ic_dialog_info;
	public static final int ICON_MAP 	= R.drawable.ic_dialog_map;
	
	private static final OnClickListener CLOSE_DIALOG_CLICK_LISTENER = new OnClickListener() {
		public void onClick(DialogInterface dialog, int buttonNumber) {
			dialog.dismiss();
		} 
	};
	
	public static class DialogConfig {
		public int icon = -1;
		public boolean cancelable = false;
		public String title = null;
		public OnCancelListener cancelListener = null;
		public OnDismissListener dismissListener;
		public OnKeyListener keyListener;
	}
	
	public static class MessageDialogConfig 
		extends DialogConfig {
		public String message = null;
		public String buttonText = null;
		public OnClickListener buttonListener = null;
	}
	
	public static class ConfirmDialogConfig 
		extends DialogConfig {
		public String message = null;
		public String yesButtonText = null;
		public String noButtonText = null;
		public DialogInterface.OnClickListener yesButtonListener = null;
		public DialogInterface.OnClickListener noButtonListener = null;
	}
	
	public static class SpinnerDialogConfig
		extends DialogConfig {
		public String message = null;
	}
	
	public static class LoadingDialogConfig
		extends DialogConfig {
		public String message = null;
		public int max = 0;
		public int progress = 0;
	}
	
	/**
	 * Configures a dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static Dialog configure(Context context, DialogConfig config, Dialog dialog) {
		
		// configure basic dialog stuff
		dialog.setCancelable(config.cancelable);
		dialog.setTitle(config.title!=null ? config.title : context.getText(R.string.dialog_alert_title));
		if (config.cancelListener!=null) { dialog.setOnCancelListener(config.cancelListener); }
		if (config.dismissListener!=null) { dialog.setOnDismissListener(config.dismissListener); }
		if (config.keyListener!=null) { dialog.setOnKeyListener(config.keyListener); }
		
		// configure specific stuff
		if (config instanceof MessageDialogConfig) {
			return configureMessageDialog(context, (MessageDialogConfig)config, (AlertDialog)dialog);
			
		} else if (config instanceof SpinnerDialogConfig) {
			return configureSpinnerDialog(
				context, (SpinnerDialogConfig)config, (ProgressDialog)dialog);
			
		} else if (config instanceof LoadingDialogConfig) {
			return configureLoadingDialog(
				context, (LoadingDialogConfig)config, (ProgressDialog)dialog);
			
		} else if (config instanceof ConfirmDialogConfig) {
			return configureConfirmDialog(
				context, (ConfirmDialogConfig)config, (AlertDialog)dialog);
		}
		
		// wtf?
		throw new IllegalArgumentException("Unknown Dialog type for configure");
	}
	
	/**
	 * Configures an alert dialog.
	 * @param context
	 * @param config
	 * @param dialog
	 * @return
	 */
	public static AlertDialog configureMessageDialog(
		Context context, MessageDialogConfig config, AlertDialog dialog) {
		dialog.setIcon(config.icon==-1 ? ICON_ALERT : config.icon);
		dialog.setMessage(config.message);
		dialog.setButton(
			config.buttonText!=null ? config.buttonText : context.getString(R.string.ok), 
			config.buttonListener!=null ? config.buttonListener : CLOSE_DIALOG_CLICK_LISTENER);
		return dialog;
	}
	
	/**
	 * Configures a progress dialog.
	 * @param context
	 * @param config
	 * @param dialog
	 * @return
	 */
	public static ProgressDialog configureSpinnerDialog(
		Context context, SpinnerDialogConfig config, ProgressDialog dialog) {
		dialog.setIcon(config.icon==-1 ? ICON_INFO : config.icon);
		dialog.setMessage(config.message);
		dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		return dialog;
	}
	
	/**
	 * Configures a progress dialog.
	 * @param context
	 * @param config
	 * @param dialog
	 * @return
	 */
	public static ProgressDialog configureLoadingDialog(
		Context context, LoadingDialogConfig config, ProgressDialog dialog) {
		dialog.setIcon(config.icon==-1 ? ICON_INFO : config.icon);
		dialog.setMessage(config.message);
		dialog.setMax(config.max);
		dialog.setProgress(config.progress);
		dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
		return dialog;
	}
	
	/**
	 * Configures a progress dialog.
	 * @param context
	 * @param config
	 * @param dialog
	 * @return
	 */
	public static AlertDialog configureConfirmDialog(
		Context context, ConfirmDialogConfig config, AlertDialog dialog) {
		dialog.setIcon(config.icon==-1 ? ICON_ALERT : config.icon);
		dialog.setMessage(config.message);
		dialog.setButton(DialogInterface.BUTTON_POSITIVE, 
			config.yesButtonText!=null ? config.yesButtonText : context.getString(R.string.ok), 
			config.yesButtonListener!=null ? config.yesButtonListener : CLOSE_DIALOG_CLICK_LISTENER);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, 
			config.noButtonText!=null ? config.noButtonText : context.getString(R.string.cancel), 
			config.noButtonListener!=null ? config.noButtonListener : CLOSE_DIALOG_CLICK_LISTENER);
		return dialog;
	}
	
	/**
	 * Creates a dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static Dialog create(Context context, DialogConfig config) {
		if (config instanceof MessageDialogConfig) {
			return createMessageDialog(context, (MessageDialogConfig)config);
		} else if (config instanceof SpinnerDialogConfig) {
			return createSpinnerDialog(context, (SpinnerDialogConfig)config);
		} else if (config instanceof LoadingDialogConfig) {
			return createLoadingDialog(context, (LoadingDialogConfig)config);
		} else if (config instanceof ConfirmDialogConfig) {
			return createConfirmDialog(context, (ConfirmDialogConfig)config);
		}
		throw new IllegalArgumentException("Unknown Dialog type for create");
	}
	
	/**
	 * Creates an alert dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static AlertDialog createMessageDialog(Context context, MessageDialogConfig config) {
		return (AlertDialog)configure(
			context, config, new AlertDialog.Builder(context).create());
	}
	
	/**
	 * Convenience method for creating simple short lived
	 * message dialogs.
	 * @param context the context
	 * @param message the message
	 * @param title the title
	 * @param icon the icon
	 * @return the dialog
	 */
	public static AlertDialog createMessageDialog(
		Context context, String message, String title, int icon) {
		MessageDialogConfig config = new MessageDialogConfig();
		config.icon 	= icon;
		config.title	= title;
		config.message	= message;
		return createMessageDialog(context, config);
	}
	
	/**
	 * Convenience method for creating simple short lived
	 * message dialogs.
	 * @param context the context
	 * @param message the message
	 * @param title the title
	 * @param icon the icon
	 * @return the dialog
	 */
	public static AlertDialog createMessageDialog(
		Context context, String message, String title) {
		MessageDialogConfig config = new MessageDialogConfig();
		config.title	= title;
		config.message	= message;
		return createMessageDialog(context, config);
	}
	
	/**
	 * Convenience method for creating simple short lived
	 * message dialogs.
	 * @param context the context
	 * @param message the message
	 * @param title the title
	 * @param icon the icon
	 * @return the dialog
	 */
	public static AlertDialog createMessageDialog(Context context, String message) {
		MessageDialogConfig config = new MessageDialogConfig();
		config.message	= message;
		return createMessageDialog(context, config);
	}
	
	/**
	 * Creates a progress dialog dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static ProgressDialog createSpinnerDialog(Context context, SpinnerDialogConfig config) {
		return (ProgressDialog)configure(context, config, new ProgressDialog(context));
	}
	
	/**
	 * Creates a progress dialog dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static ProgressDialog createLoadingDialog(Context context, LoadingDialogConfig config) {
		return (ProgressDialog)configure(context, config, new ProgressDialog(context));
	}
	
	/**
	 * Creates a confirm dialog dialog.
	 * @param context
	 * @param config
	 * @return
	 */
	public static AlertDialog createConfirmDialog(Context context, ConfirmDialogConfig config) {
		
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setIcon(config.icon!=-1 ? config.icon : ICON_ALERT);
		builder.setCancelable(config.cancelable);
		builder.setTitle(config.title!=null ? config.title :context.getString(R.string.dialog_alert_title));
		builder.setMessage(config.message);
		builder.setPositiveButton(
			config.yesButtonText!=null ? config.yesButtonText : context.getString(R.string.yes),
			config.yesButtonListener!=null ? config.yesButtonListener : CLOSE_DIALOG_CLICK_LISTENER);
		builder.setNegativeButton(
			config.noButtonText!=null ? config.noButtonText : context.getString(R.string.no),
			config.noButtonListener!=null ? config.noButtonListener : CLOSE_DIALOG_CLICK_LISTENER);

		if (config.cancelListener!=null) {
			builder.setOnCancelListener(config.cancelListener);
		}
		if (config.dismissListener!=null) {
			builder.setOnKeyListener(config.keyListener);
		}
		
		AlertDialog dialog = builder.create();
		
		if (config.dismissListener!=null) {
			dialog.setOnDismissListener(config.dismissListener);
		}
		
		return dialog;
	}
	
}
